package synchronize;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyThread implements Runnable{
    private static int count;

    private String name;

    public MyThread(String name){
        this.name = name;
    }

//    private synchronized void incre(){
//        System.out.println(Thread.currentThread().getName() + ": " + (count++));
//    }

//    private void incre(){
//        synchronized (this){
//            System.out.println(Thread.currentThread().getName() + ": " + (count++));
//        }
//    }

    private void incre(){
        synchronized (MyThread.class){
            System.out.println(Thread.currentThread().getName() + ": " + (count++));
        }
    }

    @Override
    public void run() {

        for (int i = 0; i < 5; i++) {
                incre();

        }
    }
}

class MyThread2 implements Callable<Integer> {
    private static int count;

    private String name;

    public MyThread2(String name){
        this.name = name;
    }


    private void incre(){
        synchronized (MyThread.class){
            System.out.println(Thread.currentThread().getName() + ": " + (count++));
        }
    }

    @Override
    public Integer call() throws Exception{

        for (int i = 0; i < 5; i++) {
            incre();

        }
        return count;
    }
}

public class TestSynchronizeClass {

    public static void main(String[] args) {
//        MyThread myThread1 = new MyThread("thread 1");
//        MyThread myThread2 = new MyThread("thread 2");
//        MyThread myThread3 = new MyThread("thread 3");
//        new Thread(myThread1).start();
//        new Thread(myThread2).start();
//        new Thread(myThread3).start();

        MyThread2 myThread1 = new MyThread2("thread 1");
        MyThread2 myThread2 = new MyThread2("thread 2");
        MyThread2 myThread3 = new MyThread2("thread 3");

        FutureTask<Integer> integerFutureTask1 = new FutureTask<>(myThread1);
        FutureTask<Integer> integerFutureTask2 = new FutureTask<>(myThread2);
        FutureTask<Integer> integerFutureTask3 = new FutureTask<>(myThread3);

        new Thread(integerFutureTask1).start();
        new Thread(integerFutureTask2).start();
        new Thread(integerFutureTask3).start();

    }
}
